#ifndef __IOT_DEFINES_H__
#define __IOT_DEFINES_H__

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#else

#ifndef bool
#define bool uint8_t
#endif

#ifndef false
#define false 0
#endif

#ifndef true
#define true 1
#endif
#endif

#define STR_LEN 128

#define SERVER_ADDRESS_SIZE 6

#define SERVER_TYPE_UNKNOWN 0
#define SERVER_TYPE_DEVICE_GW 1
#define SERVER_TYPE_API_GW 2
#define SERVER_TYPE_NTP 3
#define SERVER_TYPE_OTA 4

#define PROTO_TYPE_UNKNOWN 0
#define PROTO_TYPE_HTTP 1
#define PROTO_TYPE_HTTPS 2
#define PROTO_TYPE_MQTT 3
#define PROTO_TYPE_MQTTS 4
#define PROTO_TYPE_NTP 5

typedef struct {
	char ip[32];
	char domain[32];
	uint8_t server_type; // device gw; api gw; ntp; ota
	uint8_t proto_type; // http/https; mqtt/mqtts; ntp
	uint8_t priority;
	uint8_t reserve;
}server_address_t;

typedef struct {
	char device_uid[64];
	char product_code[64];
	char secret[64];
	char activate_secret[64];
	char sn[64];

	// device gateway | api gateway | ntp
	server_address_t servers[SERVER_ADDRESS_SIZE];
} iot_param_t;

#define OTA_MODULE_ID_ALL 0
#define OTA_MODULE_ID_WIFI 1
#define OTA_MODULE_ID_MCU 2

typedef struct {
	char version[32];
	char release_notes[256];
	char check_sum[128];
	char download_url[256];
	uint8_t force_upgrade;
} iot_ota_info_t;

typedef enum {
	//成功
	RC_OK = 0,
	//未知错误
	RC_FAIL = 1,
	//仅允许单实例运行
	RC_ONLY_SINGLE_INSTNACE = 2,
	//非法参数
	RC_INVALID_PARAMS = 3,	
	//SDK未初始化
	RC_NOT_INITED = 4,
	//设备未激活
	RC_NO_ACTIVATE = 5,
	//设备已激活
	RC_ACTIVATED = 6,
	//已断开连接
	RC_DISCONNECTED = 7,
	//连接mqtt服务器失败
	RC_CONNECT_MQTT_SERVER_FAIL = 8,
	//初始化mqtt失败
	RC_INIT_MQTT_FAIL = 9,
	//协议序列化失败
	RC_SERIALIZE_FAIL = 10,
	RC_MQTT_SUBSCRIBE_FAIL = 11,
	RC_MQTT_PUBLISH_FAIL = 12,
	//绑定失败
	RC_BIND_FAIL = 13,
	//已绑定
	RC_BOUND = 14,
	//协议构建失败
	RC_PROTOCOL_BUILD_FAIL = 15,
	//协议错误
	RC_PROTOCOL_FAIL = 16,
	//AES失败
	RC_ENCRYPT_FAIL = 17,
	RC_HTTP_BUILD_FAIL = 18,
	RC_HTTP_REQUEST_FAIL = 19,
	RC_HTTP_RESPONSE_FAIL = 20,
	RC_HTTP_INVALID_RESPONSE = 21,
	RC_NTP_FAIL = 22,
	RC_CALL_TIMEOUT = 23,
	RC_CALL_ERROR = 24,
	//传输失败
	RC_TRANSPORT_SEND_FAIL = 25,
    RC_GET_SERVER_LIST_FAIL = 26,
	//平台返回的消息，以1000为基础
	RC_IOT_PLATFORM_BASE_ERR = 1000,
}iot_err_code_e;

typedef struct {
	char *str;
	uint32_t len;
} str_t;

#define IS_STR_EMPTY(s) (!(s)->str || (s)->len == 0)

#define CSTR(s) { .str = (char*)s, .len= strlen(s) }

typedef struct {
	char *buff;
	uint32_t len;
	uint32_t cap;
}iot_buffer_t;

typedef enum
{
    MODEL_PROP_READ       = 0x01,
    MODEL_PROP_WRITE      = 0x02,
    MODEL_PROP_REPORT     = 0x04,
} model_method_e;

typedef enum {
    IOT_VALUE_TYPE_INVALID = -1,
    IOT_VALUE_TYPE_VOID = 0,
    IOT_VALUE_TYPE_BOOL = 1,
    IOT_VALUE_TYPE_UINT8 = 2,
    IOT_VALUE_TYPE_UINT16 = 3,
    IOT_VALUE_TYPE_UINT32 = 4,
    IOT_VALUE_TYPE_UINT64 = 5,
    IOT_VALUE_TYPE_INT8 = 6,
    IOT_VALUE_TYPE_INT16 = 7,
    IOT_VALUE_TYPE_INT32 = 8,
    IOT_VALUE_TYPE_INT64 = 9,
    IOT_VALUE_TYPE_FLOAT = 10,
    IOT_VALUE_TYPE_DOUBLE = 11,
    IOT_VALUE_TYPE_STRING = 12,
    IOT_VALUE_TYPE_ENUM = 13,
    IOT_VALUE_TYPE_JSON = 14,
    IOT_VALUE_TYPE_ARRAY = 0x80,
} value_type_e;

#define IOT_VALUE_TYPE_MASK 0x7f
#define IS_ARRAY(type) ((type & IOT_VALUE_TYPE_MASK) == IOT_VALUE_TYPE_ARRAY)

#pragma pack(4)
typedef union {
	bool b;
	uint8_t u8;
	uint16_t u16;
	uint32_t u32;
	uint64_t u64;
	int8_t i8;
	int16_t i16;
	int32_t i32;
	int64_t i64;
	float f32;
	double f64;
	str_t  enum_name;
	str_t str;
} iot_base_value_t;

typedef struct {
	value_type_e type;
	uint32_t len;
	union {
		bool b;
		uint8_t u8;
		uint16_t u16;
		uint32_t u32;
		uint64_t u64;
		int8_t i8;
		int16_t i16;
		int32_t i32;
		int64_t i64;
		float f32;
		double f64;
		str_t  enum_name;
		str_t str;
		str_t array;	//json array. i.e [ 0, 1, 2] or ["0", "1", "2"]
	} value;
} iot_value_t;
#pragma pack()

typedef struct {
	str_t name;
	iot_value_t value;
} iot_prop_feature_t;

typedef iot_prop_feature_t iot_key_value_pair_t;

#define IS_FEATURE_EMPTY(fp) (IS_STR_EMPTY(&(fp)->name))

#define PROP_MAX 20
#define PROP_FEATURE_MAX 16

typedef struct _iot_model_prop{
	str_t prop_name;
	iot_prop_feature_t values[PROP_FEATURE_MAX];
} iot_model_prop_t;

typedef iot_prop_feature_t iot_method_args_t;

typedef enum {
	ALARM_UNKNOWN = 0,
	ALARM_WARN = 1,
	ALARM_ERROR,
	ALARM_FATAL,
}alarm_level_e;

typedef enum {
    CN_UNKNOWN = 0,
    CN_2G,
    CN_3G,
    CN_4G,
    CN_5G
} cn_type_e;

typedef struct {
	struct {
		str_t device_uid;
		str_t product_code;
		str_t sn;
	} base;
	struct {
		str_t ssid;
		str_t rssi;
		str_t mac;
		str_t bssid;
		uint8_t level;
	} wifi;
	struct {
		str_t sn;
		uint32_t cap;
		uint32_t act;
	}battery;
	struct {
		str_t sys;
		str_t mcu;
		str_t sdk;
		str_t hw;
	}vers;
	struct {
		str_t ip;
		str_t gw;
		str_t dns;
		str_t netmask;
	}net;
    struct {
        //Cellular network
        cn_type_e type;
        // -110dbm, -20dbm
        str_t rssi;
        // [0,100]
        uint8_t level;
    } cm_net;
} sys_info_t;


typedef struct {
	/**
	 * 属性设置回调
	 */ 
	iot_err_code_e (*on_prop_set)(void *arg, iot_model_prop_t *props, uint8_t num,
					iot_model_prop_t *return_props, uint8_t max_props, uint8_t *act_prop_num);
	/**
	 * 方法调用回调
	 */ 
	iot_err_code_e (*on_call_method)(void *arg, str_t method_name, iot_method_args_t *args, uint8_t arg_num, 
					iot_model_prop_t *return_props, uint8_t max_props, uint8_t *act_prop_num);
} iot_event_handler_t;


#define IOT_LOG_LEVEL_OFF 0
#define IOT_LOG_LEVEL_DEBUG 1
#define IOT_LOG_LEVEL_INFO 2
#define IOT_LOG_LEVEL_WARN 3
#define IOT_LOG_LEVEL_ERROR 4

/**
 * 0(OFF) 1(DEBUG) 2(INFO) 3(WARN) 4(ERROR)
 */ 
void set_iot_log_level(int level);

int get_iot_log_level();

#ifdef __cplusplus
}
#endif

#endif	/* __IOT_DEFINES_H__ */
